<!-- 
在 Vue 3 中，使用组合 API 时，可以通过  `watch`  和  `watchEffect`  函数来侦听数据的变化。这些功能使得开发者能够响应数据的变化并执行相应的逻辑。
  1.  `watch` 
  `watch`  是一个用于侦听响应式数据变化的函数。它接受两个参数：要侦听的数据源和一个回调函数，当数据源发生变化时，回调函数会被调用。
   基本用法
  import { ref, watch } from 'vue';

  export default {
    setup() {
      const count = ref(0);

      watch(count, (newValue, oldValue) => {
        console.log(`Count changed from ${oldValue} to ${newValue}`);
      });

      return {
        count
      };
    }
  };
  2. 侦听多个数据源
  可以通过将多个数据源作为数组传递给  `watch`  来侦听多个响应式数据：
  import { ref, watch } from 'vue';

  export default {
    setup() {
      const count = ref(0);
      const message = ref('Hello');

      watch([count, message], ([newCount, newMessage], [oldCount, oldMessage]) => {
        console.log(`Count changed from ${oldCount} to ${newCount}`);
        console.log(`Message changed from ${oldMessage} to ${newMessage}`);
      });

      return {
        count,
        message
      };
    }
  };
  3.  `watchEffect` 
  `watchEffect`  是一个更简单的侦听器，它会自动追踪在其回调函数中使用的响应式数据。当这些数据发生变化时，回调函数会被重新调用。

   基本用法
  import { ref, watchEffect } from 'vue';

  export default {
    setup() {
      const count = ref(0);

      watchEffect(() => {
        console.log(`Count is: ${count.value}`);
      });

      return {
        count
      };
    }
  };
  4. 选项
  在使用  `watch`  时，可以传递一个第三个参数来配置侦听器的行为，包括：
  - immediate：如果设置为  `true` ，在侦听器初始化时立即调用回调函数。
  - deep：如果设置为  `true` ，则深度侦听对象的变化。

   示例
  import { ref, watch } from 'vue';

  export default {
    setup() {
      const user = ref({ name: 'Alice', age: 25 });

      watch(user, (newValue, oldValue) => {
        console.log('User changed:', newValue);
      }, { deep: true });

      return {
        user
      };
    }
  };
  5. 总结
  在 Vue 3 的组合 API 中， `watch`  和  `watchEffect`  提供了强大的数据侦听功能。 `watch`  适用于侦听特定的数据源，而  `watchEffect`  则适合自动追踪多个响应式数据的变化。理解这些侦听器的使用场景和配置选项，可以帮助开发者更好地管理组件的状态和响应数据变化。 
-->
<template>
  <div>
    <h3>1. watch</h3>
    <button @click="message = 'Hello Watch'">修改message</button>
    <button @click="info.friend.name = 'watch-name-deep-true'">深度修改info</button>

    <h3>2. watchEffect</h3>
    <div>当前计数: {{ counter }}</div>
    <button @click="counter++">+1</button>
    <button @click="name = 'watchEffect-exec'">修改name</button>
  </div>
</template>

<script>
  import { watchEffect, watch, ref, reactive } from 'vue'

  export default {
    setup() {
      // 1.定义数据
      const message = ref("Hello World")
      const info = reactive({
        name: "watch-name",
        age: 18,
        friend: {
          name: "watch-name-friend"
        }
      })
      const counter = ref(0)
      const name = ref("watchEffect-name")

      // 1.1. 侦听数据的变化
      // watch(counter, (newValue, oldValue) => {})
      watch(message, (newValue, oldValue) => {
        console.log("01_watch-message", newValue, oldValue)
      })
      watch(info, (newValue, oldValue) => {
        console.log("02_watch-immediate", newValue, oldValue)
        console.log("02_watch-immediate", newValue === oldValue)
      }, {
        immediate: true // 立即执行
      })
      // 1.2. 监听reactive数据变化后, 获取普通对象
      watch(() => ({ ...info }), (newValue, oldValue) => {
        console.log("03_watch-immediate-deep", newValue, oldValue)
      }, {
        immediate: true, // 立即执行
        deep: true // 深度监听
      })

      // 2.1. watchEffect传入的函数默认会直接被执行
      // 2.2. 在执行的过程中, 会自动的收集依赖(依赖哪些响应式的数据)
      const stopWatch = watchEffect(() => {
        console.log("watchEffect: ", counter.value, name.value)

        // 判断counter.value > 10
        if (counter.value >= 10) {
          stopWatch() // 停止监听
        }
      })

      return {
        message,
        info,

        counter,
        name
      }
    }
  }
</script>
